package server.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;

import player.PlayerManager;
import adventure.Adventure;
import java.util.Iterator;
import server.util.tickevents.TickerEvent;

/**
 *
 * @author Michael Hanns
 *
 */
public class TickerImp extends Thread implements Ticker {

    private Broadcaster broadcaster;
    private PlayerManager players;
    private boolean ticking;
    private boolean publicServer;
    private Socket channelSocket;
    private PrintWriter channelOut;
    private ArrayList<TickerEvent> tickEvents;
    private ArrayList<TickerEvent> roundEvents;
    private Thread round;
    private int roundsPassed;

    public TickerImp(Adventure a, Broadcaster b, PlayerManager p) {
        tickEvents = new ArrayList<TickerEvent>();
        roundEvents = new ArrayList<TickerEvent>();
        broadcaster = b;
        players = p;
        ticking = false;
        roundsPassed = 0;
    }

    @Override
    public void addRoundEvent(TickerEvent e) {
        roundEvents.add(e);
    }

    @Override
    public void addTickEvent(TickerEvent e) {
        tickEvents.add(e);
    }

    @Override
    public void startTicking() {
        ticking = true;
        try {
            Runnable roundEvent = new Runnable() {
                @Override
                public void run() {
                    round();
                    System.out.println("Round run.");
                }
            };
            while (ticking) {
                Thread.sleep(5000);
                System.out.println("Running round");
                round = new Thread(roundEvent);
                round.start();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopTicking() {
        ticking = false;
    }

    private synchronized void round() {
        performRoundEvents();
        roundsPassed++;

        if (roundsPassed == 5) {
            roundsPassed = 0;
            performTickEvents();
        }
    }

    private synchronized void performRoundEvents() {
        Iterator<TickerEvent> itr = roundEvents.iterator();
        while (itr.hasNext()) {
            itr.next().executeEvent();
        }
    }

    private synchronized void performTickEvents() {
        broadcaster.broadcastTickNotification();
        if (publicServer) {
            // Stay connected to serverlist..
            channelOut.println("SETPLAYERS " + players.onlinePlayers());
        }

        Iterator<TickerEvent> itr = tickEvents.iterator();
        while (itr.hasNext()) {
            itr.next().executeEvent();
        }
    }

    @Override
    public String setChannel(String ipstr, String serverDetails) {
        String returnText = "Connected to channel " + ipstr + ".";


        try {
            InetAddress ip = InetAddress.getByName(ipstr);

            channelSocket = new Socket(ip, 724);

            channelOut = new PrintWriter(channelSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(channelSocket.getInputStream()));

            channelOut.println("ADDSERVER " + serverDetails);

            publicServer = Boolean.parseBoolean(in.readLine());
        } catch (Exception e) {
            channelSocket = null;
            channelOut = null;
            return "ERROR: Channel does not exist.";
        }

        if (publicServer) {
            return returnText;
        } else {
            return "ERROR: Not a WITNA Channel!";
        }
    }
}
